/*
Copyright (C) 2010-2011 Sylvain Martin (Spintec - CEA/CNRS/UJF/G-INP)
All rights reserved.

This file is part of the SpinToolBow

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#pragma once
#ifndef SPLOTSETSCALE_H
#define SPLOTSETSCALE_H

#include <qwt_plot.h>

#include <qwt_scale_widget.h>
#include <qwt_scale_draw.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_layout.h>

#include <QWidget>
#include <QObject>
#include <QDialog>

#include "../GeneratedFiles/ui_SPlotSetScale.h"

class SPlotSetScale;


////////////////////////////////////////////////////////////////////////////////////////////////////
/// \class	SPlot2DWidget
///
/// \brief	define a custom object for plot the 2-dimensional curves.
///
/// \author	Sylvain Martin
/// \date	2/4/2011
///
/// \remark order to use Qwt as a dll and inherit a QWT object we must define the macro in the
/// 		preprocessor QWT_DLL. in , the project need a preprocessor define
/// 		[configuration properties]->[c/c++]->[preprocessor]->[preprocessor definitions]-> QWT_DLL
/// 		(and leave the rest as it is)
///
/// It is a sub-class of QwtPlot that adds some functions, like a \c zoom, an \c autoscale
/// and a way to chose a scale (\c selectScale).
////////////////////////////////////////////////////////////////////////////////////////////////////

class SPlot2DWidget :
	public QwtPlot
{
	Q_OBJECT;

public:
	SPlot2DWidget(QWidget *parent = 0);

public slots:
	void zoom();
	void autoScale();
	void selectScale();
	void setScale(double Xmin, double Xmax, double Ymin, double Ymax);

protected:
	QwtPlotZoomer * zoomer;
	QwtPlotPanner * panner;
	SPlotSetScale * winScale;
	bool flagZoom;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \class	SPlotZoomer
///
/// \brief	(PRIVATE) sub-class of \c QwtPlotZoomer used to add a zoom to the plot widget
///
/// \author	Sylvain Martin
/// \date	2/4/2011
///
/// it is a private_class
////////////////////////////////////////////////////////////////////////////////////////////////////
class SPlotZoomer:
	public QwtPlotZoomer
{
public:
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \fn	SPlotZoomer::SPlot2DWidget(QWidget *parent)
	///
	/// \brief	Constructor.
	///
	/// \param [in,out]	the canvas of the 2D QwtPlot.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	SPlotZoomer(QwtPlotCanvas *canvas):
	  QwtPlotZoomer(canvas) {
		  setTrackerMode(AlwaysOn);
	  }

	 ////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \fn	SPlotZoomer::trackerText(QWidget *parent)
	///
	/// I do not know the real utility of this function, I picked up that in a QWT example ...
	////////////////////////////////////////////////////////////////////////////////////////////////////
	 virtual QwtText trackerText(const QwtDoublePoint &pos) const {
		QColor bg(Qt::white);
        QwtText text = QwtPlotZoomer::trackerText(pos);
        text.setBackgroundBrush(QBrush( bg ));
        return text;
    }
};

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \class	SPlotSetScale
///
/// \brief	(PRIVATE) small QDialog to let the user set a scale.
///
/// \author	Sylvain Martin
/// \date	2/4/2011
///
/// it is a private class, do not use it directly !
////////////////////////////////////////////////////////////////////////////////////////////////////
class SPlotSetScale :
	public QDialog,
	public Ui_SPlotSetScale
{
	Q_OBJECT;
public:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \fn	void SPlotSetScale::SPlotSetScale(void)
	///
	/// \brief	put the initials value for the maximum of the minimum of the 2 scales (x and y)
	///
	/// \param [in,out]	parent	If non-null, the Qt parent.
	////////////////////////////////////////////////////////////////////////////////////////////////////
	SPlotSetScale(QWidget *parent = NULL) : QDialog(parent){
		setupUi(this);
		connect(this, SIGNAL(accepted ()),this, SLOT(priv_scale()));
		connect(this, SIGNAL(accepted ()),this, SLOT(close()));
		connect(this, SIGNAL(rejected ()),this, SLOT(close()));
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \fn	void SPlotSetScale::initialValue
	///
	/// \brief	puts the initials value for the maximum of the minimum of the 2 scales (x and y)
	///
	/// \param Xmin the maximum of the x scale
	/// \param Xmax the minimum of the x scale
	/// \param Ymin the maximum of the y scale
	/// \param Ymax the minimum of the y scale
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void initialValue(double Xmin, double Xmax, double Ymin, double Ymax){
		dsbXStart->setValue(Xmin);
		dsbXStop->setValue(Xmax);
		dsbYStart->setValue(Ymin);
		dsbYStop->setValue(Ymax);
	}

signals:
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \fn	void SPlotSetScale::scaleChange
	///
	/// \brief	(SIGNAL) sends the scales selected by the user.
	///
	/// \param Xmin the maximum of the x scale
	/// \param Xmax the minimum of the x scale
	/// \param Ymin the maximum of the y scale
	/// \param Ymax the minimum of the y scale
	///
	/// this signal is send when the OK button is clicked
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void scaleChange(double Xmin, double Xmax, double Ymin, double Ymax);

private slots:
	void priv_scale(){
		double Xmin = dsbXStart->value();
		double Xmax = dsbXStop->value();
		double Ymin = dsbYStart->value();
		double Ymax = dsbYStop->value();

		emit scaleChange( Xmin,  Xmax,  Ymin,  Ymax);
		this->close();
	}
};




/*
void IncrementalPlot::appendData(double *x, double *y, int size)
{
	if ( d_data == NULL )
		d_data = new CurveData;

	if ( d_curve == NULL )
	{
		d_curve = new QwtPlotCurve("Test Curve");
		d_curve->setStyle(QwtPlotCurve::NoCurve);
		d_curve->setPaintAttribute(QwtPlotCurve::PaintFiltered);

		const QColor &c = Qt::white;
		d_curve->setSymbol(QwtSymbol(QwtSymbol::XCross,
			QBrush(c), QPen(c), QSize(5, 5)) );

		d_curve->attach(this);
	}

	d_data->append(x, y, size);
	d_curve->setRawData(d_data->x(), d_data->y(), d_data->count());


	const bool cacheMode = 
		canvas()->testPaintAttribute(QwtPlotCanvas::PaintCached);



	canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
	d_curve->draw(d_curve->dataSize() - size, d_curve->dataSize() - 1);
	canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, cacheMode);


}
*/
#endif //SPLOTSETSCALE_H